﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Mime;
using System.Threading;
using System.Threading.Tasks;
using CommandLine;
using RestSharp;
using RestSharp.Serialization.Json;

namespace ComicsDownload
{
    class Program
    {
        public class Options
        {
            [Option('v', "verbose", Required = false, HelpText = "版本号")]
            public bool Verbose { get; set; }

            [Option('b', "bookId", Required = true, HelpText = "书籍Id")]
            public int? BookId { get; set; }

            [Option('c', "chapterId", Required = false, HelpText = "章节Id")]
            public int? ChapterId { get; set; }

            [Option('e', "endChapterId", Required = false, HelpText = "结束章节Id")]
            public int? EndChapterId { get; set; }

            [Option('j', "fileId", Required = false, HelpText = "文件开始Id")]
            public int? FileId { get; set; }

            [Option('f', "saveFolder", Required = false, HelpText = "保存的路径")]
            public string SaveFolder { get; set; }

            [Option('u', "bookUrl", Required = false, HelpText = "漫画的路径")]
            public string BookUrl { get; set; }

            [Option('n', "nameCondition", Required = false, HelpText = "命名表达式")]
            public string NameCondition { get; set; }

            [Option('t', "forTest", Required = false, HelpText = "是否仅为测试")]
            public bool ForTest { get; set; }
        }

        static int RunOptionsAndReturnExitCode(Options o)
        {
            if (string.IsNullOrEmpty(o.NameCondition))
            {
                o.NameCondition = "{0}";
            }

            if (string.IsNullOrEmpty(o.BookUrl))
            {
                o.BookUrl = "http://img.elodm.com/images/mh/data/{0}/{1}/{2}.jpg";
            }

            o.EndChapterId ??= 200;

            var exitCode = 0;

            client = new RestClient("http://img.elodm.com");

            client.ClearHandlers();
            client.UserAgent = "Dalvik/2.1.0 (Linux; U; Android 9; 16s Pro Build/PKQ1.190616.001)";
            client.AddHandler("*", () =>
            {
                return new JsonDeserializer();
            });

            var url = "";
            var completeStatus = true;
            var downLoadStatus = true;

            var bookId = o.BookId.HasValue ? o.BookId.Value : 1;
            var chapterId = o.ChapterId.HasValue ? o.ChapterId.Value : 1;

            try
            {
                var pictureName = o.FileId.HasValue ? o.FileId.Value : 0;
                while (completeStatus)
                {
                    downLoadStatus = true;
                    while (downLoadStatus)
                    {
                        url = string.Format(o.BookUrl, bookId, chapterId, string.Format(o.NameCondition, pictureName));
                        downLoadStatus = Download(o.SaveFolder, url).Result;

                        if (o.ForTest)
                        {
                            break;
                        }

                        //一开始就报错
                        if (pictureName == 0 && !downLoadStatus)
                        {
                            completeStatus = false;
                        }
                        pictureName++;
                        //Thread.Sleep(100);
                    }

                    pictureName = 0;
                    //if (o.ForTest)
                    //{
                    //    break;
                    //}

                    if (chapterId > o.EndChapterId.Value)
                    {
                        break;
                    }
                    chapterId++;
                    Thread.Sleep(1000);
                }
            }
            catch (Exception ex)
            {
                exitCode = 1;
                Console.WriteLine("下载的过程中出现异常");
                Console.WriteLine(ex);
            }

            Console.WriteLine("下载完成：{0}", url);

            return exitCode;
        }

        static int HandleParseError(IEnumerable<Error> errs)
        {
            var result = -2;
            Console.WriteLine("errors {0}", errs.Count());
            if (errs.Any(x => x is HelpRequestedError || x is VersionRequestedError))
                result = -1;
            Console.WriteLine("Exit code {0}", result);
            return result;
        }

        static RestClient client;
        static void Main(string[] args)
        {
            var result = CommandLine.Parser.Default.ParseArguments<Options>(args)
                .MapResult(RunOptionsAndReturnExitCode, //in case parser sucess
                HandleParseError); //in  case parser fail

            Console.WriteLine("Return code= {0}", result);

            //System.Console.ReadKey();
        }

        private async static Task<bool> Download(string folder, string url)
        {
            if (string.IsNullOrEmpty(folder))
            {
                folder = @"D:\downloads";
            }
            var paths = url.Split('/');
            folder = Path.Combine(folder, paths[paths.Length - 3], paths[paths.Length - 2]);
            if (!Directory.Exists(folder))
            {
                Directory.CreateDirectory(folder);
            }
            Console.WriteLine("正在准备下载：{0}", url);
            RestRequest request = new RestRequest(url, Method.GET);
            //request.AddParameter("Authorization", string.Format("Bearer " + accessToken), ParameterType.HttpHeader);
            IRestResponse response = await client.ExecuteAsync(request);
            if (response.StatusCode == System.Net.HttpStatusCode.OK)
            {
                // Read bytes
                byte[] fileBytes = response.RawBytes;
                string fileName = paths.Last();
                string fullFilePath = Path.Combine(folder, fileName);
                if (File.Exists(fullFilePath))
                {
                    File.Delete(fullFilePath);
                }
                await File.WriteAllBytesAsync(fullFilePath, fileBytes);
                Console.WriteLine("保存的路径：{0}", fullFilePath);
                return true;
            }
            else if (response.StatusCode == HttpStatusCode.NotFound)
            {
                Console.WriteLine("下载失败：{0}", response.StatusCode);
                return false;
            }
            else
            {
                throw new Exception($"下载出现问题：{response.StatusCode}");
            }
        }
    }
}
